import cv2
import numpy as np

# 在 MNIST 数据集的 IDX 文件格式中，“idx3”中的“3”代表数据的维度。具体来说：
# 数据维度含义：这里的 “3” 表示图像数据有三个维度，分别是图像的高度、宽度和颜色通道数。
# 对于 MNIST 数据集中的图像，高度和宽度都是 28 像素，而颜色通道数为 1，因为 MNIST 图像是灰度图像，没有颜色信息。
# 与其他维度的区别：如果文件名中是 “idx1”，则表示数据是一维的，通常用于存储标签等一维数据；
# 如果是 “idx2”，则表示数据是二维的，一般较少见用于 MNIST 数据集相关文件。

# 准备图片数据
# 图片格式和尺寸：确保要使用的单张图片是灰度图像，且尺寸为 28×28 像素，因为 MNIST 数据集中的图像都是这种规格。
# 可以使用图像编辑软件对原始图片进行处理，如裁剪、缩放、调整对比度等操作，以满足尺寸要求。
# 如果使用编程语言处理，例如 Python 的 OpenCV 库，可以通过相关函数实现图像的读取、转换和调整尺寸等操作。
#
# 归一化处理：将图片的像素值从 0-255 范围归一化到 0-1 范围，以符合 MNIST 数据集的像素值标准。
# 在 Python 中，可以使用 NumPy 库进行归一化处理，代码示例如下：

# 读取图片
image = cv2.imread('your_image.png', cv2.IMREAD_GRAYSCALE)

# 调整图片尺寸为 28x28
image = cv2.resize(image, (28, 28))

# 归一化处理
image = image / 255.0

# 转换为 IDX 格式
# 了解 IDX 文件格式：t10k-images-idx3-ubyte 文件遵循 IDX 格式，其文件头包含魔数（magic number）、图像数量、行数和列数等信息，接着是所有图像的像素值。对于 t10k-images-idx3-ubyte 文件，魔数为 0x00000803，图像数量为 10000，行数和列数均为 28。
# 使用编程语言实现转换：以 Python 为例，可以使用 NumPy 库来处理图像数据并将其转换为 IDX 格式。首先需要安装 numpy 库
# pip install numpy

import numpy as np
import struct


def write_idx_file(filename, images):
    """
    将图像数据写入 IDX 文件。
    :param filename: 要写入的文件名。
    :param images: 图像数据列表，每个元素是一个 28x28 的 NumPy 数组。
    """
    with open(filename, 'wb') as f:
        # 写入文件头信息
        magic_number = 0x00000803
        num_images = len(images)
        num_rows = 28
        num_cols = 28
        f.write(struct.pack('>IIII', magic_number, num_images, num_rows, num_cols))

        # 写入图像数据
        for image in images:
            image.tofile(f)


# 假设已经有一个经过预处理的 28x28 的灰度图像数组 image_array
image_array = np.random.rand(28, 28)  # 这里只是生成一个随机数组作为示例，实际应使用真实图片数据

# 将单张图片包装成列表，以便写入 IDX 文件
images = [image_array] * 10000  # 由于 t10k-images-idx3-ubyte 文件中有 10000 张图片，这里将单张图片重复 10000 次作为示例

# 写入 IDX 文件
write_idx_file('t10k-images-idx3-ubyte', images)


